const root = '/static/icons/svg'

const cache = {}
const cacheObj = {}

const iconCodes = {}

let fontFamily

async function loadIcons() {
  const json = await fetch('/static/icons/iconfont.json').then(resp => resp.json())
  fontFamily = json.font_family
  json.glyphs.forEach((icon) => {
    iconCodes[icon.font_class] = String.fromCodePoint(icon.unicode_decimal)
    // iconCodes[icon.font_class] = `&#x${icon.unicode};`
    // iconCodes[icon.font_class] = `\\u${icon.unicode}`
  })
}

function getSvgPath(element, name) {
  const pathItems = element.getElementsByTagName('path')
  for (const item of pathItems) {
    const path = item.getAttribute('d')
    if (!path) {
      continue
    }
    return path
  }
  throw new Error(`SVG 图标 ${name} 无效，找不到包含 d 的 path 节点`)
}

function isAlphabet(ch) {
  ch = ch.toLowerCase()
  return ch >= 'a' && ch <= 'z';
}

function deepClone(obj) {
  if (obj === null) return null
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)
  if (typeof (obj) !== 'object') return obj
  let clone
  if (Array.isArray(obj)) {
    clone = []
    obj.forEach(function (item, index) {
      clone[index] = deepClone(item)
    })
  } else {
    clone = {}
    for (let key in obj) {
      // eslint-disable-next-line
      if (obj.hasOwnProperty(key)) {
        clone[key] = deepClone(obj[key])
      }
    }
  }
  return clone
}

function isObject(item) {
  return item && typeof (item) === 'object' && !Array.isArray(item)
}

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    })
  } else {
    obj[key] = value
  }
  return obj
}

function merge(target, source) {
  if (isObject(target) && isObject(source)) {
    for (let key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, _defineProperty({}, key, {}))
        merge(target[key], source[key])
      } else {
        Object.assign(target, _defineProperty({}, key, source[key]))
      }
    }
  } else if (Array.isArray(target) && Array.isArray(source)) {
    // 数组类型的属性，合并而不替换
    target.push.apply(target, [...source.filter(function (item) {
      return target.indexOf(item) === -1
    })])
  } else {
    Object.assign(target, _defineProperty({}, source, source))
  }
  return target
}

function deepMerge() {
  for (var _len = arguments.length, sources = new Array(_len), _key = 0; _key < _len; _key++) {
    sources[_key] = arguments[_key]
  }
  const target = sources.shift() || {}
  sources.forEach(function (source) {
    merge(target, source)
  })
  return target
}

const util = {
  async getSvg(name) {
    if (cache[name]) {
      return cache[name]
    }
    const url = `${root}/${name}.svg`
    const content = await fetch(url).then(resp => resp.text())
    const el = document.createElement('div')
    el.innerHTML = content
    const path = getSvgPath(el, name)
    cache[name] = path
    return path
  },
  getSvgSync(name, decode) {
    const path = cache[name]
    if (!decode) {
      return path
    }
    if (cacheObj[name]) {
      return cacheObj[name]
    }
    const obj = []
    let item
    for (let index = 0; index < path.length; index++) {
      const ch = path[index]
      if (isAlphabet(ch)) {
        if (item && item.length) {
          obj.push(item)
        }
        item = [ch, []]
        continue
      }
      item[1].push(ch)
    }
    if (item && item.length) {
      obj.push(item)
    }

    obj.forEach(item => {
      const value = item[1]
      if (!value.length) {
        item.length = 1
        return
      }
      const temp = value.join('').split(' ')
      temp.forEach((t, i) => {
        item[i + 1] = temp[i]
      })
    })
    cacheObj[name] = obj
    return obj
  },
  loadIcons,
  getIconCode(name) {
    return iconCodes[name] || ''
  },
  getFontFamily() {
    return fontFamily
  },
  deepClone,
  deepMerge
}

export default util
